package com.buddy.summary.code.algorithm;

import java.util.Arrays;

public class PriorityQueue {
    //最大优先队列,基于二叉堆——最大堆
    private int[] array;
    private int size;
    public PriorityQueue(){
        //队列初始长度为32
        array = new int[32];
    }

    public void enQueue(int key){
        if (size > array.length)
            resize();
        array[size++] = key;
        upAdjust();
    }

    public int deQueue() throws Exception {
        if (size < 0){
            throw new Exception("the queue is empty!");
        }
        int heap = array[0];
        array[0] = array[--size];
        downAdjust();
        return heap;
    }


    private void upAdjust() {
        int childIndex = size - 1;
        int parentIndex = (childIndex -1)/2;
        int temp = array[childIndex];
        while (childIndex > 0 && temp > array[parentIndex]){
            array[childIndex] = array[parentIndex];
            childIndex = parentIndex;
            parentIndex = childIndex/2;
        }
        array[childIndex] = temp;
    }

    private void downAdjust() {
        int parentIndex = 0;
        int temp = array[parentIndex];
        int childIndex = 1;
        while (childIndex < size){
            //找到最大child
            if (childIndex + 1 < size && array[childIndex +1] > array[childIndex]){
                childIndex ++;
            }
            //如果parent大于最大child，可以退出
            if (temp >= array[childIndex]){
                break;
            }
            array[parentIndex] = array[childIndex];
            parentIndex = childIndex;
            childIndex = 2*parentIndex+1;
        }
        array[parentIndex] = temp;
    }

    private void resize() {
        int newSize = this.size *2;
        this.array = Arrays.copyOf(this.array,newSize);
    }

    public static void main(String[] args) throws Exception {
        PriorityQueue priorityQueue = new PriorityQueue();
        priorityQueue.enQueue(3);
        priorityQueue.enQueue(5);
        priorityQueue.enQueue(10);
        priorityQueue.enQueue(2);
        priorityQueue.enQueue(7);
        int length = priorityQueue.size;
        for (int i=0;i<length;i++){
            System.out.println(priorityQueue.deQueue());
        }
    }
}
